package com.linkmcn.uaa.controller;

import com.alibaba.fastjson.JSON;
import com.linkmcn.core.api.Result;
import com.linkmcn.core.base.CurrentUser;
import com.linkmcn.redis.core.RedisService;
import com.linkmcn.uaa.cache.UserCache;
import com.linkmcn.uaa.constants.AuthConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 自定义Oauth2自定义返回格式
 *
 * @author apple
 */
@RestController
@RequestMapping("/oauth")
@AllArgsConstructor
@Api(tags = "Oauth2管理")
public class OauthController {

    private final TokenEndpoint tokenEndpoint;

    private HttpServletRequest request;

    private RedisService redisService;

    @GetMapping("/token")
    @ApiOperation(value = "用户登录Get", notes = "用户登录Get")
    public Result<?> getAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {

        return custom(tokenEndpoint.getAccessToken(principal, parameters).getBody());
    }

    @PostMapping("/token")
    @ApiOperation(value = "用户登录Post", notes = "用户登录Post")
    public Result<?> postAccessToken(Principal principal, @RequestBody Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        return custom(tokenEndpoint.postAccessToken(principal, parameters).getBody());
    }

    /**
     * 自定义返回格式
     *
     * @param accessToken 　Token
     * @return Result
     */
    private Result<?> custom(OAuth2AccessToken accessToken) {
        Map<String, Object> resultMap = new HashMap<>(2);
        DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) accessToken;
        resultMap.put("token", token);
        Map<String, Object> data = new LinkedHashMap<>(token.getAdditionalInformation());
        Long userId = (Long) data.get("userId");
        Long tenantId = (Long) data.get("tenantId");

        CurrentUser currentUser = UserCache.get(userId, tenantId);
        if (currentUser != null) {
            resultMap.put("currentUser", currentUser);
            UserCache.clear(userId, tenantId);
        }
        String tokenKey = AuthConstants.USER_TOKEN + userId + "::" + tenantId;
        redisService.set(tokenKey, JSON.toJSONString(currentUser), AuthConstants.LOGIN_EXPIRE_TIME);
        return Result.data(resultMap);
    }
}
